(PYTHON) Day - 22 Regex and Parsing(1)

Reference

  • 문제 출처 - HackerRank
  • 파이썬 연습 - Practice - Python

개인적인 생각과 상상으로 작성한 내용들이 포함되어 있습니다
문제를 풀고 Discussion Tab을 참고하며 코드 스타일을 개선하려고 노력하고자 합니다


HackerRank


Regex and Parsing

기본개념

정규 표현식 시작하기 - 점프 투 파이썬
파이썬 정규 표현식 - Google for Education

주의해야하는 메타 문자
메타 문자 중 ^[] 문자 클래스 안에 있을 때랑 밖에 있을 때 의미가 다른 것을 주의!!

[^0-9] # 숫자를 제외한 문자만 매치
[^abc] # a, b, c를 제외한 모든 문자와 매치
^a # a로 시작하는 문자
'''
a # 매치
aaa # 매치
baaa # 매치 안됨
'''

자주 사용하는 문자 클래스

  • \d - 숫자와 매치, [0-9]와 동일한 표현식이다.
  • \D - 숫자가 아닌 것과 매치, [^0-9]와 동일한 표현식이다.
  • \s - whitespace 문자와 매치, [ \t\n\r\f\v]와 동일한 표현식이다. 맨 앞의 빈 칸은 공백문자를 의미한다.
  • \S - whitespace 문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일한 표현식이다.
  • \w - 문자+숫자(alphanumeric)와 매치, [a-zA-Z0-9_]와 동일한 표현식이다.
  • \W - 문자+숫자(alphanumeric)가 아닌 문자와 매치, [^a-za-z0-9_]와 동일한 표현식이다.

패턴 매칭

search()
패턴이 발견되는 첫번째 위치를 찾는다


> > > import re
> > > print(bool(re.search(r"ly","similarly")))
> > > True
> > > print(re.search(r"ly","similarly"))
> > > <re.Match object; span=(7, 9), match='ly'>

match()
문자열의 첫 부분이 패턴과 일치하는지 확인한다


> > > import re
> > > print(bool(re.match(r"ly","similarly")))
> > > False
> > > print(re.match(r"ly","similarly"))
> > > None
> > > print(bool(re.match(r"ly","ly should be in the beginning")))
> > > True
> > > print(re.match(r"ly","ly should be in the beginning"))
> > > <re.Match object; span=(0, 2), match='ly'>

구분 (split)

split()
re 모듈의 split() 함수는 여러 구분자를 동시에 사용하여 구분할 수 있는 장점이 있다


> > > import re
> > > re.split(r"-","+91-011-2711-1111")
> > > ['+91', '011', '2711', '1111']
> > > re.split(r"[@\.]", "username@hackerrank.com")
> > > ['username', 'hackerrank', 'com']
> > >

그룹 (group)

음.. dict 자료형으로 정리할 때 유용할 것 같다

group()


> > > import re
> > > m = re.match(r'(\w+)@(\w+)\.(\w+)','username@hackerrank.com')
> > > m.group(0) # The entire match
> > > 'username@hackerrank.com'
> > > m.group(1) # The first parenthesized subgroup.
> > > 'username'
> > > m.group(2) # The second parenthesized subgroup.
> > > 'hackerrank'
> > > m.group(3) # The third parenthesized subgroup.
> > > 'com'
> > > m.group(1,2,3) # Multiple arguments give us a tuple.
> > > ('username', 'hackerrank', 'com')

groups()


> > > import re
> > > m = re.match(r'(\w+)@(\w+)\.(\w+)','username@hackerrank.com')
> > > m.groups()
> > > ('username', 'hackerrank', 'com')

groupdict()


> > > m = re.match(r'(?P<user>\w+)@(?P<website>\w+)\.(?P<extension>\w+)','myname@hackerrank.com')
> > > m.groupdict()
> > > {'website': 'hackerrank', 'user': 'myname', 'extension': 'com'}

검색 (find)

findall()


> > > import re
> > > re.findall(r'\w','http://www.hackerrank.com/')
> > > ['h', 't', 't', 'p', 'w', 'w', 'w', 'h', 'a', 'c', 'k', 'e', 'r', 'r', 'a', 'n', 'k', 'c', 'o', 'm']

finditer()


> > > import re
> > > re.finditer(r'\w','http://www.hackerrank.com/')
> > > <callable-iterator object at 0x0266C790>
> > > map(lambda x: x.group(),re.finditer(r'\w','http://www.hackerrank.com/'))
> > > ['h', 't', 't', 'p', 'w', 'w', 'w', 'h', 'a', 'c', 'k', 'e', 'r', 'r', 'a', 'n', 'k', 'c', 'o', 'm']

치환

sub()
간단한 기본 예제

import re

#Squaring numbers
def square(match):
number = int(match.group(0))
return str(number\*\*2)

print re.sub(r"\d+", square, "1 2 3 4 5 6 7 8 9")

# output: 1 4 9 16 25 36 49 64 81

흔히 html 문서에서 tag 들을 없앨 때 자주 사용된다

import re

html = """

<head>
<title>HTML</title>
</head>
<object type="application/x-flash"
data="your-file.swf"
width="0" height="0">
<!-- <param name="movie" value="your-file.swf" /> -->
<param name="quality" value="high"/>
</object>
"""

print re.sub("(<!--.*?-->)", "", html) #remove comment
output

<head>
<title>HTML</title>
</head>
<object type="application/x-flash"
data="your-file.swf"
width="0" height="0">

<param name="quality" value="high"/>
</object>